package configuracion;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import sesion_beans.EstudianteEJBLocal;
import sesion_beans.GrupoEJBLocal;
import sesion_beans.NotaEJBLocal;
import sesion_beans.ProfesorEJBLocal;
import sesion_beans.ProgramaEJBLocal;
import vos.Estudiante;
import vos.Grupo;
import vos.Nota;
import vos.Profesor;
import vos.Programa;

@ManagedBean
@SessionScoped
public class ProfesorBean {

	//-------------------------------------------------------------------------
	// Atributos
	//-------------------------------------------------------------------------
	
	@EJB(name = "ProfesorEJB/local")
	private ProfesorEJBLocal profesorEJB;
	
	@EJB(name = "ProgramaEJB/local")
	private ProgramaEJBLocal programaEJB;
	
	@EJB(name = "GrupoEJB/local")
	private GrupoEJBLocal grupoEJB;
	
	@EJB(name = "EstudianteEJB/local")
	private EstudianteEJBLocal estudianteEJB;
	
	@EJB(name = "NotaEJB/local")
	private NotaEJBLocal notaEJB;
	
	/** Es el profesor */
	private Profesor profesor = new Profesor();
	
	/** Es el nombre del programa */
	private String programa;
	
	/** Es el grupo que se elige a modificar */
	private String grupoElegido;
	
	/** El estudiante al cual se le asignara la nota */
	private String estudianteElegido = "";
	
	/** La nota que se le asignara al estudiante */
	private String nota;
	
	/** Es la accion a realizar */
	private String accion = "registrar";
	
	//-------------------------------------------------------------------------
	// Metodos
	//-------------------------------------------------------------------------
	
	/**
	 * Obtiene el programa del profesor
	 * @return programa El programa del profesor que se quiere obtener
	 */
	public String getPrograma() {
		return programa;
	}

	/**
	 * Asigna el programa al profesor
	 * @param programa El programa que se va a asignar
	 */
	public void setPrograma(String programa) {
		this.programa = programa;
	}

	/**
	 * Obtiene el profesor
	 * @return profesor El administrativo que se quiere obtener
	 */
	public Profesor getProfesor() {
		return profesor;
	}

	/**
	 * Asigna un profesor
	 * @param profesor El profesor que se va a asignar
	 */
	public void setProfesor(Profesor profesor) {
		this.profesor = profesor;
	}
	
	/**
	 * Obtiene todos los profesores de la base de datos
	 * @return La lista de profesores que estan registrados en la base de datos
	 */
	public List<Profesor> getprofesores(){
		return profesorEJB.obtenerProfesores();
	}
	
	/**
	 * Agrega un profesor a la base de datos
	 */
	public void adicionarProfesor(){
		try {
			Programa programabus = programaEJB.buscar(this.programa+"");
			System.out.println(programa);
			profesor.setPrograma(programabus);
			profesor.setTipoPersona("Profesor");
			System.out.println(profesor.getTipoPersona()+"");
			profesorEJB.adicionar(profesor);
			agregarProfesorPrograma(profesor, programabus);
			programaEJB.actualizar(programabus);
			profesor = new Profesor();
			FacesMessage mensaje = new FacesMessage("El profesor ha sido agregado");
			FacesContext.getCurrentInstance().addMessage(null, mensaje);
		} catch (Exception e) {
			FacesMessage mensaje = new FacesMessage(FacesMessage.SEVERITY_ERROR ,"El profesor ya existe","El profesor ya existe");
			FacesContext.getCurrentInstance().addMessage(null, mensaje);
		}
		
	}
	
	/**
	 * Elimina un profesor de la base de datos
	 * @return la pagina que se redireccionara
	 */
	public String eliminarProfesorDeBD(){
		System.out.println(profesor.getCedula());
		profesorEJB.eliminar(profesor);
		FacesMessage mensaje = new FacesMessage("El profesor ha sido eliminado");
		FacesContext.getCurrentInstance().addMessage(null, mensaje);
		return "/Paginas/paginasAgregar/agregarProfesor.xhtml";
	}
	
	/**
	 * Actualiza un profesor
	 */
	public void actualizarProfesorDeBD(){
		profesorEJB.actualizar(profesor);
		FacesMessage mensaje = new FacesMessage("El profesor ha sido actualizado");
		FacesContext.getCurrentInstance().addMessage(null, mensaje);
		profesor =  new Profesor();
		accion = "registrar";
	}

	/**
	 * Obtiene la interfaz local de un profesor
	 * @return La interfaz local de un profesor
	 */
	public ProfesorEJBLocal getProfesorEJB() {
		return profesorEJB;
	}
	
	/**
	 * Asigna la interfaz local de un profesor
	 * @param profesorEJB La interfaz local de un profesor
	 */
	public void setProfesorEJB(ProfesorEJBLocal profesorEJB) {
		this.profesorEJB = profesorEJB;
	}
	
	/**
	 * Agrega un profesor a un programa dado como parametro
	 * @param profesor El profesor que se va a agregar al programa
	 * @param programa El programa al cual se le va a agregar el profesor
	 */
	private void agregarProfesorPrograma(Profesor profesor, Programa programa){
		List<Profesor> profesores = programaEJB.obtenerProfesores(programa.getNombre());
		profesores.add(profesor);
		programa.setProfesores(profesores);
	}
	
	/**
	 * Obtiene la cedula de todos los profesores
	 * @return La cedula de todos los profesores
	 */
	public List<String> getcedulaProfesores(){
		return profesorEJB.obtenerCedulaProfesores();
	}
	
	
	/**
	 * Modifica la accion a realizar
	 */
	public void cancelar(){
		accion = "registrar";
		profesor = new Profesor();
	}

	/**
	 * Obtiene la accion a realizar
	 * @return La accion a realizar
	 */
	public String getAccion() {
		return accion;
	}

	/**
	 * Asigna la accion a realizar
	 * @param accion La accion a realizar
	 */
	public void setAccion(String accion) {
		this.accion = accion;
	}
	
	/**
	 * Obtiene el grupo que se ha elegido
	 * @return El grupo que se ha elegido
	 */
	public String getGrupoElegido() {
		return grupoElegido;
	}

	/**
	 * Asigna el grupo que se ha elegido
	 * @param grupoElegido El grupo que se ha elegido
	 */
	public void setGrupoElegido(String grupoElegido) {
		this.grupoElegido = grupoElegido;
	}
	
	/**
	 * Obtiene el estudiante al cual se le asiganara la nota
	 * @return El estudiante al cual se le asiganara la nota
	 */
	public String getEstudianteElegido() {
		return estudianteElegido;
	}

	/**
	 * Asigna el estudiante al cual se le asiganara la nota
	 * @param estudianteElegido El estudiante al cual se le asiganara la nota
	 */
	public void setEstudianteElegido(String estudianteElegido) {
		this.estudianteElegido = estudianteElegido;
	}
	
	/**
	 * Obtiene la nota que se le asignara al estudiante
	 * @return La nota que se le asignara al estudiante
	 */
	public String getNota() {
		return nota;
	}

	/**
	 * Asigna la nota que se le asignara al estudiante
	 * @param nota La nota que se le asignara al estudiante
	 */
	public void setNota(String nota) {
		this.nota = nota;
	}
	
	/**
	 * Obtiene los grupos en que el profesor dicta una materia
	 * @return Los grupos en que el profesor dicta una materia
	 */
	public List<String> getGrupos(){
		LoginModuleBean bean = (LoginModuleBean)obtenerLoginBean();
		profesor = bean.getProfesor();
		List<Grupo> grupos = profesorEJB.obtenerGrupos(profesor.getCedula());
		ArrayList<String> nombreGrupos = new ArrayList<String>();
		for (int i = 0; i < grupos.size(); i++) {
			String materia = grupos.get(i).getMateria().getNombre();
			int numeroGrupo = grupos.get(i).getNummeroDeGrupo();
			nombreGrupos.add(materia + ", Grupo " + numeroGrupo);
		}
		return nombreGrupos;
	}
	
	/**
	 * Obtiene el loginBean
	 * @return EL loginBean
	 */
	public Object obtenerLoginBean(){
		FacesContext facesContext =  FacesContext.getCurrentInstance();
		ELContext elContext = facesContext. getELContext();
		ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
		ValueExpression expression = expressionFactory.createValueExpression(elContext, "#{loginModuleBean}", Object.class);
		return  expression.getValue(elContext);
	}
	
	/**
	 * Obtiene los estudiantes del grupo elegido
	 * @return Los estudiantes del grupo elegido
	 */
	public List<String> getEstudiantes(){
		String[] division = grupoElegido.split(",");
		List<Nota> notas = grupoEJB.obtenerNotas(profesor.getCedula(), division[0]);
		ArrayList<String> estudiantes = new ArrayList<String>();
		for (int i = 0; i < notas.size(); i++) {
			estudiantes.add(notas.get(i).getEstudiante().getCedula());
		}
		return estudiantes;
	}
	
	/**
	 * Obtiene el nombre del estudiante al cual se le va a asignar la nota
	 * @return El nombre del estudiante al cual se le va a asignar la nota
	 */
	public String getNombreEstudiante(){
		Estudiante estudiante = estudianteEJB.buscar(estudianteElegido);
		if (estudiante == null) {
			List<String> estudiantes = getEstudiantes();
			Estudiante estudianteBuscado = estudianteEJB.buscar(estudiantes.get(0));
			return estudianteBuscado.getNombreyApellido();
		}
		return estudiante.getNombreyApellido();
	}
	
	/**
	 * Obtiene los numeros de las notas
	 * @return Los numeros de las notas
	 */
	public ArrayList<String> getNumeroNotas(){
		ArrayList<String> notas = new ArrayList<String>();
		int entero = 0;
		int decimal = 0;
		boolean empezar = false;
		int indice = 0;
		for (int i = 0; i < 5; i++) {
			if (empezar) 
				entero++;
			for (int j = 0; j < 10; j++) {
				notas.add(indice, entero+"."+decimal);
				decimal++;
				indice++;
			}
			empezar = true;
			decimal = 0;
		}
		notas.add(50, 5.0+"");
		return notas;
	}
	
	/**
	 * Asigna la nota al estudiante elegido
	 */
	public void asignarNota(){
		String[] division = grupoElegido.split(",");
		List<Nota> notas = grupoEJB.obtenerNotas(profesor.getCedula(), division[0]);
		Nota nota = obtenerNota(notas,estudianteElegido);
		nota.setNota(Double.parseDouble(this.nota));
		notaEJB.actualizar(nota);
		Estudiante estudiante = estudianteEJB.buscar(estudianteElegido);
		String nombre = estudiante.getNombreyApellido();
		FacesMessage mensaje = new FacesMessage("La nota "+ this.nota +" ha sido asignada exitosamente al estudiante " + nombre + " ");
		FacesContext.getCurrentInstance().addMessage(null, mensaje);
	}

	/**
	 * Obtiene la nota del estudiante seleccionado en el comboBox
	 * @param notas Las notas del grupo
	 * @param cedulaSeleccionada La cedula que se ha seleccionado en el comoboBox
	 * @return La nota donde el estudiante es el seleccionado
	 */
	private Nota obtenerNota(List<Nota> notas, String cedulaSeleccionada) {
		for (int i = 0; i < notas.size(); i++) {
			Nota nota = notas.get(i);
			String cedulEestudiante = nota.getEstudiante().getCedula();
			if (cedulaSeleccionada.equals(cedulEestudiante)) {
				return nota;
			}
		}
		return null;
	}
	
}
